<template>
  <div class="fm-style">
    <a-form-model
      ref="generateForm"
      :size="data.config.size"
      :model="models"
      :rules="rules"
      :layout="data.config.formLayout"
      :wrapperCol="
        data.config.formLayout == 'horizontal'
          ? { span: data.config.wrapperCol.span }
          : {}
      "
      :labelCol="
        data.config.formLayout == 'horizontal'
          ? { span: data.config.labelCol.span }
          : {}
      "
      :labelAlign="data.config.labelPosition"
    >
      <template v-for="item in data.list">
        <template v-if="item.type == 'grid'">
          <a-row
            :key="item.key"
            type="flex"
            :gutter="item.options.gutter ? item.options.gutter : 0"
            :justify="item.options.justify"
            :align="item.options.align"
            v-show="!item.options.hidden"
          >
            <a-col
              v-for="(col, colIndex) in item.columns"
              :key="colIndex"
              :span="col.span"
            >
              <template v-for="citem in col.list">
                <template v-if="citem.type == 'blank'">
                  <a-form-model-item
                    :label="citem.name"
                    :prop="citem.model"
                    :key="citem.key"
                    @on-change="onInputChange"
                  >
                    <slot :name="citem.model" :model="models"></slot>
                  </a-form-model-item>
                </template>
                <genetate-form-item
                  v-else
                  :key="citem.key"
                  :models.sync="models"
                  :remote="remote"
                  :rules="rules"
                  :widget="citem"
                  @on-change="onInputChange"
                ></genetate-form-item>
              </template>
            </a-col>
          </a-row>
        </template>

        <template v-else-if="item.type == 'tabs'">
          <a-tabs
            v-model="item.active"
            :key="item.key"
            :type="item.options.type"
            :tabPosition="item.options.tabPosition"
            v-show="!item.options.hidden"
          >
            <a-tab-pane
              v-for="tab in item.columns"
              :tab="tab.label"
              :name="tab.name"
              :key="tab.name"
            >
              <template v-for="citem in tab.list">
                <a-form-model-item
                  v-if="citem.type == 'blank'"
                  :label="citem.name"
                  :prop="citem.model"
                  :key="citem.key"
                >
                  <slot :name="citem.model" :model="models"></slot>
                </a-form-model-item>
                <genetate-form-item
                  v-else
                  :key="citem.key"
                  :models.sync="models"
                  :remote="remote"
                  :rules="rules"
                  :widget="citem"
                  @on-change="onInputChange"
                ></genetate-form-item>
              </template>
            </a-tab-pane>
          </a-tabs>
        </template>

        <template v-else-if="item.type == 'html'">
          <div
            v-html="
              item.options.defaultValue === undefined
                ? ''
                : item.options.defaultValue
            "
            :key="item.key"
            v-show="!item.options.hidden"
          ></div>
        </template>

        <template v-else-if="item.type == 'blank'">
          <a-form-model-item
            :label="item.name"
            :prop="item.model"
            :key="item.key"
            v-show="!item.options.hidden"
            @on-change="onInputChange"
          >
            <slot :name="item.model" :model="models"></slot>
          </a-form-model-item>
        </template>

        <template v-else-if="item.type == 'divider'">
          <div :key="item.key" v-show="!item.options.hidden">
            <a-divider orientation="left">{{ item.name }}</a-divider>
          </div>
        </template>

        <template v-else>
          <genetate-form-item
            :key="item.key"
            :models.sync="models"
            :rules="rules"
            :widget="item"
           @on-change="onInputChange"
            :remote="remote"
          ></genetate-form-item>
        </template>
      </template>
    </a-form-model>
  </div>
</template>

<script>
import GenetateFormItem from "./GenerateFormItem";

export default {
  name: "fm-generate-form",
  components: {
    GenetateFormItem
  },
  props: ["data", "remote", "value", "insite"],
  data() {
    return {
      generateForm: this.$form.createForm(this, { name: "generateForm" }),
      models: {},
      rules: {}
    };
  },
  created() {
    this.generateModle(this.data.list);
  },
  mounted() {},
  methods: {
    generateModle(genList) {
      for (let i = 0; i < genList.length; i++) {
        if (genList[i].type === "grid" || genList[i].type === "tabs") {
          genList[i].columns.forEach(item => {
            this.generateModle(item.list);
          });
        } else {
          if (
            this.value &&
            Object.keys(this.value).indexOf(genList[i].model) >= 0
          ) {
            this.models[genList[i].model] = this.value[genList[i].model];
          } else {
            if (genList[i].type === "blank") {
              this.$set(
                this.models,
                genList[i].model,
                genList[i].options.defaultType === "String"
                  ? ""
                  : genList[i].options.defaultType === "Object"
                  ? {}
                  : []
              );
            } else {
              this.models[genList[i].model] = genList[i].options.defaultValue;
            }
          }
          if (this.rules[genList[i].model]) {
            this.rules[genList[i].model] = [
              ...this.rules[genList[i].model],
              ...genList[i].rules.map(item => {
                if (item.pattern) {
                  return { ...item, pattern: eval(item.pattern) };
                } else {
                  return { ...item };
                }
              })
            ];
          } else {
            this.rules[genList[i].model] = [
              ...genList[i].rules.map(item => {
                if (item.pattern) {
                  return { ...item, pattern: eval(item.pattern) };
                } else {
                  return { ...item };
                }
              })
            ];
          }
        }
      }
    },
    getData() {
      const that = this;
      return new Promise((resolve, reject) => {
        that.$refs["generateForm"].validate(valid => {
          if (valid) {
            resolve(this.models);
          } else {
            reject(this.models);
          }
        });
      });
    },
    reset() {
      const that = this;
      that.$refs.generateForm.resetFields();
    },
    onInputChange() {
      this.$emit("on-change", null);
    },
    fieldsDisabled(models, disable) {
      this.disableModle(this.data.list, models, disable);
    },
    disableModle(genList, models, disable) {
      if (models.length === 0) {
        genList.forEach(gen => {
          if (gen.type === "grid" || gen.type === "tabs") {
            gen.columns.forEach(item => {
              this.disableModle(item.list, models, disable);
            });
          } else {
            gen["options"]["disabled"] = disable;
          }
        });
      } else {
        genList.forEach(gen => {
          if (gen.type === "grid" || gen.type === "tabs") {
            gen.columns.forEach(item => {
              this.disableModle(item.list, models, disable);
            });
          } else {
            models.forEach(m => {
              if (m === gen["model"]) {
                gen["options"]["disabled"] = disable;
              }
            });
          }
        });
      }
    },
    fieldsHidden(models, hidden) {
      this.hiddenModle(this.data.list, models, hidden);
    },
    hiddenModle(genList, models, hidden) {
      genList.forEach(gen => {
        if (gen.type === "grid" || gen.type === "tabs") {
          gen.columns.forEach(item => {
            this.hiddenModle(item.list, models, hidden);
          });
        } else {
          models.forEach(m => {
            if (m === gen["model"]) {
              // hidden
              gen["options"]["hidden"] = hidden;
            }
          });
        }
      });
    },
    fromDisabled() {
      this.disableModle(this.data.list, [], true);
    },
    refresh() {}
  },
  watch: {
    data: {
      deep: true,
      handler(val) {
        this.generateModle(val.list);
      }
    },
    value: {
      deep: true,
      handler(val) {
        this.models = { ...this.models, ...val };
      }
    }
  }
};
</script>

<style lang="scss">
// @import '../styles/cover.scss';
p {
  margin: 0;
}
pre {
  border-radius: 3px;
  white-space: pre-wrap;
  margin-bottom: 5px;
  margin-top: 5px;
  padding: 5px 10px;
}
pre.ql-syntax {
  background-color: #23241f;
  color: #f8f8f2;
  overflow: visible;
}
</style>
